﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.TextManager.Interop;

namespace PovTeam.Pkg_PovrayProject
{
    class PovCodeCompletion : IVsCompletionSet
    {

        #region IVsCompletionSet Members

        #region Keyword List
        public static readonly string[] keywords = new string[]
        {
"aa_level",
"aa_threshold",
"abs",
"absorption",
"accuracy",
"acos",
"acosh",
"adaptive",
"adc_bailout",
"agate",
"agate_turb",
"albedo",
"all",
"all_intersections",
"alpha",
"altitude",
"always_sample",
"ambient",
"ambient_light",
"angle",
"aoi",
"aperture",
"append",
"arc_angle",
"area_illumination",
"area_light",
"array",
"asc",
"ascii",
"asin",
"asinh",
"assumed_gamma",
"atan",
"atan2",
"atand",
"atanh",
"autostop",
"average",
"b_spline",
"background",
"bezier_spline",
"bicubic_patch",
"bitwise_and",
"bitwise_or",
"bitwise_xor",
"black_hole",
"blob",
"blue",
"blur_samples",
"bokeh",
"bounded_by",
"box",
"boxed",
"bozo",
"break",
"brick",
"brick_size",
"brightness",
"brilliance",
"bump_map",
"bump_size",
"bumps",
"camera",
"case",
"caustics",
"ceil",
"cells",
"charset",
"checker",
"chr",
"circular",
"clipped_by",
"clock",
"clock_delta",
"clock_on",
"collect",
"color",
"color_map",
"colour",
"colour_map",
"component",
"composite",
"concat",
"cone",
"confidence",
"conic_sweep",
"conserve_energy",
"contained_by",
"control0",
"control1",
"coords",
"cos",
"cosh",
"count",
"crackle",
"crand",
"cube",
"cubic",
"cubic_spline",
"cubic_wave",
"cutaway_textures",
"cylinder",
"cylindrical",
"datetime",
"debug",
"declare",
"default",
"defined",
"degrees",
"density",
"density_file",
"density_map",
"dents",
"deprecated",
"df3",
"difference",
"diffuse",
"dimension_size",
"dimensions",
"direction",
"disc",
"dispersion",
"dispersion_samples",
"dist_exp",
"distance",
"div",
"double_illuminate",
"eccentricity",
"else",
"elseif",
"emission",
"end",
"error",
"error_bound",
"evaluate",
"exp",
"expand_thresholds",
"exponent",
"exterior",
"extinction",
"face_indices",
"facets",
"fade_color",
"fade_colour",
"fade_distance",
"fade_power",
"falloff",
"falloff_angle",
"false",
"fclose",
"file_exists",
"filter",
"final_clock",
"final_frame",
"finish",
"fisheye",
"flatness",
"flip",
"floor",
"focal_point",
"fog",
"fog_alt",
"fog_offset",
"fog_type",
"fopen",
"for",
"form",
"frame_number",
"frequency",
"fresnel",
"function",
"gamma",
"gather",
"gif",
"global_lights",
"global_settings",
"gradient",
"granite",
"gray",
"gray_threshold",
"green",
"height_field",
"hexagon",
"hf_gray_16",
"hierarchy",
"hypercomplex",
"hollow",
"if",
"ifdef",
"iff",
"ifndef",
"image_height",
"image_map",
"image_pattern",
"image_width",
"importance",
"include",
"initial_clock",
"initial_frame",
"input_file_name",
"inside",
"inside_vector",
"int",
"interior",
"interior_texture",
"internal",
"interpolate",
"intersection",
"intervals",
"inverse",
"ior",
"irid",
"irid_wavelength",
"isosurface",
"jitter",
"jpeg",
"julia",
"julia_fractal",
"lambda",
"lathe",
"leopard",
"light_group",
"light_source",
"linear_spline",
"linear_sweep",
"ln",
"load_file",
"local",
"location",
"log",
"look_at",
"looks_like",
"low_error_factor",
"macro",
"magnet",
"major_radius",
"mandel",
"map_type",
"marble",
"material",
"material_map",
"matrix",
"max",
"maximum_reuse",
"max_extent",
"max_gradient",
"max_intersections",
"max_iteration",
"max_sample",
"max_trace",
"max_trace_level",
"media",
"media_attenuation",
"media_interaction",
"merge",
"mesh",
"mesh2",
"metallic",
"method",
"metric",
"min",
"min_extent",
"minimum_reuse",
"mm_per_unit",
"mod",
"mortar",
"natural_spline",
"nearest_count",
"no",
"no_bump_scale",
"no_image",
"no_radiosity",
"no_reflection",
"no_shadow",
"noise_generator",
"normal",
"normal_indices",
"normal_map",
"normal_vectors",
"now",
"number_of_waves",
"object",
"octaves",
"off",
"offset",
"omega",
"omnimax",
"on",
"once",
"onion",
"open",
"orient",
"orientation",
"orthographic",
"ovus",
"panoramic",
"parallel",
"parametric",
"pass_through",
"pattern",
"pavement",
"perspective",
"pgm",
"phase",
"phong",
"phong_size",
"photons",
"pi",
"pigment",
"pigment_map",
"pigment_pattern",
"planar",
"plane",
"png",
"point_at",
"poly",
"polynomial",
"poly_wave",
"polygon",
"pot",
"pow",
"ppm",
"precision",
"precompute",
"premultiplied",
"pretrace_end",
"pretrace_start",
"prism",
"prod",
"projected_through",
"pwr",
"quadratic_spline",
"quadric",
"quartic",
"quaternion",
"quick_color",
"quick_colour",
"quilted",
"radial",
"radians",
"radiosity",
"radius",
"rainbow",
"ramp_wave",
"rand",
"range",
"ratio",
"read",
"reciprocal",
"recursion_limit",
"red",
"reflection",
"reflection_exponent",
"refraction",
"render",
"repeat",
"rgb",
"rgbf",
"rgbft",
"rgbt",
"right",
"ripples",
"rotate",
"roughness",
"samples",
"save_file",
"scale",
"scallop_wave",
"scattering",
"seed",
"select",
"shadowless",
"sin",
"sine_wave",
"sinh",
"sint8",
"sint16be",
"sint16le",
"sint32be",
"sint32le",
"size",
"sky",
"sky_sphere",
"slice",
"slope",
"slope_map",
"smooth",
"smooth_triangle",
"solid",
"sor",
"spacing",
"specular",
"sphere",
"sphere_sweep",
"spherical",
"spiral1",
"spiral2",
"spline",
"split_union",
"spotlight",
"spotted",
"sqr",
"sqrt",
"square",
"srgb",
"srgbf",
"srgbt",
"srgbft",
"statistics",
"str",
"strcmp",
"strength",
"strlen",
"strlwr",
"strupr",
"sturm",
"substr",
"subsurface",
"sum",
"superellipsoid",
"switch",
"sys",
"t",
"tan",
"tanh",
"target",
"text",
"texture",
"texture_list",
"texture_map",
"tga",
"thickness",
"threshold",
"tiff",
"tightness",
"tile2",
"tiles",
"tiling",
"tolerance",
"toroidal",
"torus",
"trace",
"transform",
"translate",
"translucency",
"transmit",
"triangle",
"triangle_wave",
"triangular",
"true",
"ttf",
"turb_depth",
"turbulence",
"type",
"u",
"uint8",
"uint16be",
"uint16le",
"u_steps",
"ultra_wide_angle",
"undef",
"union",
"up",
"use_alpha",
"use_color",
"use_colour",
"use_index",
"utf8",
"uv_indices",
"uv_mapping",
"uv_vectors",
"v",
"v_steps",
"val",
"variance",
"vaxis_rotate",
"vcross",
"vdot",
"version",
"vertex_vectors",
"vlength",
"vnormalize",
"vrotate",
"vstr",
"vturbulence",
"warning",
"warp",
"water_level",
"waves",
"while",
"width",
"wood",
"wrinkles",
"write",
"x",
"y",
"yes",
"z"};

        #endregion


        private CompletionItem[] completionSet;
        private TextSpan extent;

        public PovCodeCompletion(CompletionItem[] completionSet, TextSpan extent)
        {
            this.completionSet = completionSet;
            this.extent = extent;
        }

        public int GetBestMatch(string pszSoFar, int iLength, out int piIndex, out uint pdwFlags)
        {
            string matchedWord = completionSet.Where(i => i.Text.StartsWith(pszSoFar)).FirstOrDefault().Text;
            if (matchedWord != null)
            {
                piIndex = Array.IndexOf(completionSet, matchedWord);
                if (matchedWord == pszSoFar)
                {
                    pdwFlags = (uint)UpdateCompletionFlags.GBM_UNIQUE;
                }
                else
                {
                    pdwFlags = (uint)UpdateCompletionFlags.GBM_SELECT;
                }
            }
            else
            {
                pdwFlags = (uint)UpdateCompletionFlags.GBM_SELECT;
                piIndex = 0;
            }
            return VSConstants.S_OK;
        }

        public int GetCount()
        {
            return completionSet.Length;
        }

        public int GetDescriptionText(int iIndex, out string pbstrDescription)
        {
            pbstrDescription = completionSet[iIndex].Desc;
            return VSConstants.S_OK;
        }

        public int GetDisplayText(int iIndex, out string ppszText, int[] piGlyph = null)
        {
            ppszText = completionSet[iIndex].Text;
            if (piGlyph != null)
            {
                piGlyph[0] = completionSet[iIndex].Icon;
            }
            return VSConstants.S_OK;
        }

        public uint GetFlags()
        {
            return (uint)(UpdateCompletionFlags.CSF_INITIALEXTENTKNOWN | UpdateCompletionFlags.CSF_HAVEDESCRIPTIONS);
        }

        public int GetImageList(out IntPtr phImages)
        {
            phImages = IntPtr.Zero;
            return VSConstants.S_OK;
        }

        public int GetInitialExtent(out int piLine, out int piStartCol, out int piEndCol)
        {
            piLine = extent.iStartLine;
            piStartCol = extent.iStartIndex;
            piEndCol = extent.iEndIndex;
            return VSConstants.S_OK;
        }

        public int OnCommit(string pszSoFar, int iIndex, int fSelected, ushort cCommit, out string pbstrCompleteWord)
        {
            pbstrCompleteWord = completionSet[iIndex].Text;
            return VSConstants.S_OK;
        }

     

        public void Dismiss()
        {
          
        }

        #endregion
    }
}
